package com.example.caoben_back.utils;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * JWT工具类，用于生成和验证JWT令牌
 */
@Component
@Data
@ConfigurationProperties(prefix = "jwt")
public class JWTUtil {
    private String secret;
    private Long expireTime;
    
    /**
     * 签名生成JWT Token
     * @param data 要存储在token中的数据（字符串形式）
     * @param expireTime token过期时间（毫秒）
     * @param secret 签名密钥
     * @return 生成的JWT Token
     */
    public static String sign(String data, long expireTime, String secret) {
        Date date = new Date(System.currentTimeMillis() + expireTime);
        Algorithm algorithm = Algorithm.HMAC256(secret);
        return JWT.create()
                .withClaim("body", data)
                .withExpiresAt(date)
                .sign(algorithm);
    }

    /**
     * 签名生成JWT Token（对象形式数据）
     * @param data 要存储在token中的数据（对象形式）
     * @param expireTime token过期时间（毫秒）
     * @param secret 签名密钥
     * @param <T> 数据对象类型
     * @return 生成的JWT Token
     */
    public static <T> String sign(T data, long expireTime, String secret) {
        Date date = new Date(System.currentTimeMillis() + expireTime);
        Algorithm algorithm = Algorithm.HMAC256(secret);
        String jsonStr = JSON.toJSONString(data);
        return JWT.create()
                .withClaim("body", jsonStr)
                .withExpiresAt(date)
                .sign(algorithm);
    }

    /**
     * 从JWT Token中获取载荷数据并转换为指定对象
     * @param token JWT Token
     * @param clazz 目标对象类型
     * @param <T> 目标对象泛型
     * @return 载荷数据转换后的对象
     */
    public static <T> T getPayload(String token, Class<T> clazz) {
        DecodedJWT jwt = JWT.decode(token);
        String jsonStr = jwt.getClaim("body").asString();
        return JSON.parseObject(jsonStr, clazz);
    }

    /**
     * 从JWT Token中获取载荷数据（字符串形式）
     * @param token JWT Token
     * @return 载荷数据字符串
     */
    public static String getPayload(String token) {
        DecodedJWT jwt = JWT.decode(token);
        return jwt.getClaim("body").asString();
    }

    /**
     * 获取JWT Token的过期时间
     * @param token JWT Token
     * @return 过期时间戳（毫秒）
     */
    public Long getExpireTime(String token) {
        DecodedJWT jwt = JWT.decode(token);
        return jwt.getExpiresAt().getTime();
    }

    /**
     * 验证JWT Token的有效性
     * @param token JWT Token
     * @param secret 签名密钥
     * @return 验证结果，有效返回true，否则返回false
     */
    public static boolean verify(String token, String secret) {
        if (token == null || token.isEmpty()) {
            return false;
        }
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm).build();
            verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }
}